/****************************************************************
 * <strong>MFDataTable虚拟化数据表</strong>
 *
 * <p>
 *MFDataTable虚拟化数据表 
 * </p>
 *
 * @author AndyZhang 2011 cnet2001@163.com
 * @version 0.1
 * ToDo:2011-11-29 支持 BigTable
 ***************************************************************/

package com.thinkwide.data.ormapping.datatable;

import com.thinkwide.data.core.MFString;
import com.thinkwide.data.ormapping.page.MFPageDataTable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MFDataTable {
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    private MFDataColumns columns;
    private MFDataRows rows;
    private MFPageDataTable pages;

    private String tableName;
    private String modifyFields;
    private String insertFields;
    private MFDataUpdateType updateType;
    private String primaryFields;

    public MFDataTable() {
        columns = new MFDataColumns();
        rows = new MFDataRows(this);
        pages = new MFPageDataTable();
        updateType = MFDataUpdateType.utAuto;
    }

    public MFDataRow newRow() {
        MFDataRow row = new MFDataRow();
        row.setDataRows(rows);
        rows.add(row);
        return row;
    }

    public boolean isEmpty() {
        return this.getRows().isEmpty();
    }

    public void addRow(MFDataRow row) {
        row.setDataRows(rows);
        rows.add(row);
    }


    public void removeRow(MFDataRow row) {
        rows.remove(row);
    }


    public MFDataTable transformTable(boolean needTitle) throws MFDataColumnException {
        MFDataTable table = new MFDataTable();

        table.addColumn(this.getColumns().getColumn(0).getTitle(),
                this.getColumns().getColumn(0).getField());

        for (MFDataRow row : this.getRows()) {

            table.addColumn(row.getString(0), row.getString(0));

        }


        for (MFDataColumn col : this.getColumns()) {
            if (col.getIndex() == 0) {
                continue;
            }
            int j = 0;
            MFDataRow rowA = table.newRow();
            rowA.setValue(0, col.getTitle());


            for (MFDataRow row : this.getRows()) {

                rowA.setValue(j + 1, row.getValue(col.getIndex()));

                j++;

            }
        }
        return table;
    }


    public void copyStructFrom(MFDataTable table) throws MFDataColumnException {
        for (MFDataColumn col : table.getColumns()) {
            MFDataColumn column = MFDataColumn.clone(col);
            this.addColumn(column);
        }
    }

    public void copyDataFrom(MFDataTable table) throws MFDataColumnException {
        for (MFDataRow row : table.getRows()) {
            MFDataRow arow = this.newRow();
            arow.setState(row.getState());
            for (MFDataColumn col : table.getColumns()) {
                if (this.getColumns().hasColumn(col.getField())) {
                    arow.setValue(col.getField(), row.getValue(col.getField()));
                }
            }
        }
    }

    public MFDataColumn addColumn(MFDataColumn column) {
        return columns.addColumn(column);
    }

    public void removeColumn(MFDataColumn column) {
        columns.removeColumn(column);
    }

    public MFDataColumn addColumn(String fieldName) {
        return columns.addColumn(new MFDataColumn(fieldName));
    }

    public MFDataColumn addColumn(String fieldName, String title) {
        return columns.addColumn(new MFDataColumn(fieldName, title));
    }

    public void setColumns(MFDataColumns columns) {
        this.columns = columns;
    }

    public MFDataColumns getColumns() {
        return columns;
    }

    public void setRows(MFDataRows rows) {
        this.rows = rows;
        rows.setDataTable(this);
    }

    public MFDataRows getRows() {
        return rows;
    }

    public void setPages(MFPageDataTable pages) {
        this.pages = pages;
    }

    public MFPageDataTable getPages() {
        return pages;
    }


    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getTableName() {
        return tableName;
    }


    public void setModifyFields(String modifyFields) {
        this.modifyFields = modifyFields;
    }

    public String getModifyFields() {
        return modifyFields;
    }

    public List<String> getModifyFieldList() throws Exception {
        List<String> list = null;

        if (MFString.notNullOrEmpty(modifyFields)) {
            String[] str = modifyFields.split(",");
            list = Arrays.asList(str);
        }
        if (list.isEmpty() && MFString.isNullOrEmpty(tableName))
            throw new Exception("updateField or tableName is empty!");
        return list;
    }


    public List<String> getPrimaryFieldList() throws Exception {
        List<String> list = null;

        if (MFString.notNullOrEmpty(primaryFields)) {
            String[] str = primaryFields.split(",");
            list = Arrays.asList(str);
        } else {
            list = new ArrayList<String>();
            for (MFDataColumn col : this.getColumns()) {
                if (col.isPrimaryKey()) {
                    list.add(col.getField());
                }
            }
        }
        if (list.isEmpty()) {
            throw new Exception("Please set PrimaryKey!");
        }
        return list;
    }

    public void setPrimaryFields(String primaryFields) {
        this.primaryFields = primaryFields;
    }

    public String getPrimaryFields() {
        return primaryFields;
    }

    public void setTableAndPrimary(String tableName, String primaryFields) {
        this.primaryFields = primaryFields;
        this.tableName = tableName;
    }

    public void createColumnsByModifyFields() throws Exception {
        List<String> list = getModifyFieldList();
        for (String item : list) {
            getColumns().addColumn(new MFDataColumn(item));
        }
    }

    public void createColumnsByInsertFields() throws Exception {
        List<String> list = getInsertFieldList();
        for (String item : list) {
            getColumns().addColumn(new MFDataColumn(item));
        }
    }

    public void createColumnsByFields(List<String> list) throws Exception {
        for (String item : list) {
            getColumns().addColumn(new MFDataColumn(item));
        }
    }

    public void createColumnsByFields(String fields) throws Exception {
        List<String> list = null;

        if (MFString.notNullOrEmpty(fields)) {
            String[] str = fields.split(",");
            list = Arrays.asList(str);
        }
        createColumnsByFields(list);
    }

    public void createColumnsByPrimaryFields() throws Exception {
        List<String> list = getPrimaryFieldList();
        for (String item : list) {
            getColumns().addColumn(new MFDataColumn(item));
        }
    }

    public void setInsertFields(String insertFields) {
        this.insertFields = insertFields;
    }

    public String getInsertFields() {
        return insertFields;
    }

    public List<String> getInsertFieldList() throws Exception {
        List<String> list = null;

        if (MFString.notNullOrEmpty(insertFields)) {
            String[] str = insertFields.split(",");
            list = Arrays.asList(str);
        }
        if (list.isEmpty() && MFString.isNullOrEmpty(tableName))
            throw new Exception("insertField or tableName is empty!");
        return list;
    }

    public void setUpdateType(MFDataUpdateType updateType) {
        this.updateType = updateType;
    }

    public MFDataUpdateType getUpdateType() {
        return updateType;
    }

}

